package swa.telco.impl;

import java.util.Collection;
import javax.jws.WebService;
import org.apache.cxf.jaxws.*;
import org.apache.cxf.frontend.*;

import java.lang.reflect.*;
import java.io.*;

import swa2012.telco.broker.Broker;
import swa2012.telco.broker.beans.Client;
import swa2012.telco.broker.beans.Message;
import swa2012.telco.broker.beans.Provider;

import swa.telco.interfaces.*;

public class MiniClient {
	
	/**
	 * http://www.m.......x.at:..../Provider/ProviderService
	 * http://www.m.......x.at:..../Provider/BrokerCallbackService
	 *
	 */
	
	// ... ("https://swa.............../TelcoBroker/BrokerService")
	final String ADDRESS = "http://www.m.......x.at:..../Provider/ProviderService";
	// ... (swa2012.telco.broker.Broker.class)
	final Class SERVICECLASS = swa.telco.interfaces.ClientProviderInt.class;

	public static void main(String[] args) {
		System.out.println("Starting \"MiniClient\" ...");
		new MiniClient(args.length>0 ? (args[0].equals("verbose")?true:false) : false);
	}

	public MiniClient(boolean verbose) {
//no		JaxWsClientFactoryBean factory = new JaxWsClientFactoryBean();
		JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
		System.out.println("Connecting to address: " + ADDRESS);
		factory.setAddress(ADDRESS);
		factory.setServiceClass(SERVICECLASS);
		swa.telco.interfaces.ClientProviderInt provider = (swa.telco.interfaces.ClientProviderInt) factory.create();
//		swa2012.telco.broker.Broker broker = (swa2012.telco.broker.Broker) factory.create();
//		System.out.println("javax.jws.WebService.endpointInterface="+broker.endpointInterface());
		
		if (verbose) {
			Class[] interfaces=provider.getClass().getInterfaces();
			System.out.println("Implemented interfaces@provider:"+interfaces.length);
			for (int i=0; i<interfaces.length;++i) {
				String wSInterface=interfaces[i].getName();
				System.out.println("interface#"+(i+1)+"@provider: " + wSInterface);			
			}
			Field[] fields=provider.getClass().getFields();
			System.out.println("Implemented fields@provider:"+fields.length);
			for (int i=0; i<fields.length;++i) {
				String wSField=fields[i].getName();
				System.out.println("field#"+(i+1)+"@provider: " + wSField);			
			}
			Method[] methods=provider.getClass().getMethods();
			System.out.println("Implemented methods@provider:"+methods.length);
			for (int i=0; i<methods.length;++i) {
				String wSName=methods[i].getName();                                        					
				System.out.println("method#"+(i+1)+"@provider: " + wSName);
				if (wSName.indexOf("Endpoint")>-1)
					try {
						System.out.println("Invoking ... \"endpoint\":\n" +
							methods[i].invoke(provider,null).toString());
					}
					catch (IllegalAccessException iae) {
					}
					catch (IllegalArgumentException iae) {
					}
					catch (InvocationTargetException ite) {
					}
				
			}
		}

		String anyClient = "a.......";
		
		try {
			for (int i=0; i<3; ++i) {
				System.out.print(".");
				Thread.sleep(1000L);
			}
			System.out.print("\n");
  	        } catch (InterruptedException e) {
  	        }
		
		//register+de-&printout
		System.out.println("Trying to register client \"" + anyClient + "\" ...");
//ok		swa2012.telco.broker.beans.Client client = new swa2012.telco.broker.beans.Client();
//		client.setID(anyClient);
//NO		client.setProvider(provider);
		swa2012.telco.broker.beans.Client client = provider.register(anyClient); //client.getID()
		System.out.println("Client registered: " + client.toString());
		
		try {
			for (int i=0; i<3; ++i) {
				System.out.print(".");
				Thread.sleep(1000L);
			}
			System.out.print("\n");
  	        } catch (InterruptedException e) {
  	        }
  	        
		Collection<Client> clients = provider.listAllClients();
		System.out.println("Listing all clients ...");
		//try "me"
		Client me=null; 
		for (Client c : clients) {
			if (c.getID().equals("client-1338980297041")) me=c; //anyClient
			System.out.println(c.toString());
		}

		try {
			for (int i=0; i<3; ++i) {
				System.out.print(".");
				Thread.sleep(1000L);
			}
			System.out.print("\n");
  	        } catch (InterruptedException e) {
  	        }

  	        cont(); 	        
  	        System.out.println("Trying to send message to " + me.getID() + " ...");
		String msg="NEW-HELLO";  	        
  	        if (provider.sendMessage(new swa2012.telco.broker.beans.Message(client,me,msg,new java.util.Date().getTime())))
  	        	System.out.println("Message \"" + msg + "\" successfully sent to " + me.getID() + ".");
  	        else System.out.println("Couldn't send message \"" + msg + "\" to " + me.getID() + ".");

  	        cont();
  	        System.out.println("Trying to receive message for " + client.getID() + " ...");
  	        Collection<Message> messages = provider.getMessages(client.getID());
  	        for (Message m : messages)
  	        	System.out.println(m.toString() + "\n" + m.getText());

  	        cont();
		System.out.println("Trying to deregister client \"" + client.getID() + "\": " + (provider.deregister(client.getID()) ? "OK":"Error occured."));
		
		try {
			for (int i=0; i<3; ++i) {
				System.out.print(".");
				Thread.sleep(1000L);
			}
			System.out.print("\n");
  	        } catch (InterruptedException e) {
  	        }

		clients = provider.listAllClients();
		System.out.println("Listing all clients ...");
		for (Client c : clients)
			System.out.println(c.toString());

//NO		System.out.println("Result of \"Broker.ping()\":" + broker.ping());

/**HM?		Collection<swa2012.telco.broker.beans.Provider> providers = broker.listProviders();
		System.out.println("Listing providers ...");
		for (swa2012.telco.broker.beans.Provider p : providers)
			System.out.println(p.toString());
		
		Collection<Client> clients = broker.listClients();
		System.out.println("Listing clients ...");
		for (Client c : clients)
			System.out.println(c.toString());
*/		
		System.out.println("Ending \"MiniClient\".");
	}
	private void cont() {
  	        System.out.println("For continuing type: \"continue\"");
  	        try {
			String CurLine = ""; // Line read from standard in
			InputStreamReader converter = new InputStreamReader(System.in);
			BufferedReader in = new BufferedReader(converter);
			while (!(CurLine.equals("continue"))){
				CurLine = in.readLine();
				if (!(CurLine.equals("continue"))){
					System.out.println("For continuing type: \"continue\"");
				}
			}
		}
		catch (IOException ioe) {
			System.out.println(ioe.toString());
		}
	}
}

